package com.hgyc.mom.common.service.impl;

import com.hgyc.mom.common.config.MinioConfig;
import com.hgyc.mom.common.exception.file.FileException;
import com.hgyc.mom.common.service.FileServiceStrategy;
import com.hgyc.mom.common.util.file.FileUtils;
import io.minio.GetObjectArgs;
import io.minio.RemoveObjectArgs;
import io.minio.errors.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.io.InputStream;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;

/**
 * Minio文件服务
 * @author fwj
 * @since 2025/4/24
 */
@Service
@ConditionalOnProperty(name = "mom.upload.strategy", havingValue = "minio")
public class MinioFileServiceImpl implements FileServiceStrategy {

    @Autowired
    private MinioConfig minioConfig;

    @Override
    public String uploadFile(MultipartFile file) throws FileException {
        try {
            return FileUtils.uploadMinio(file);
        } catch (IOException e) {
            throw new FileException("文件上传失败", e);
        }
    }

    @Override
    public String uploadFile(MultipartFile file, String folder) throws FileException {
        try {
            return FileUtils.uploadMinio(file, folder);
        } catch (IOException e) {
            throw new FileException("文件上传失败", e);
        }
    }

    @Override
    public byte[] downloadFile(String filePath) throws FileException {
        if (filePath == null || filePath.trim().isEmpty()) {
            throw new FileException("文件路径不能为空");
        }

        try (InputStream inputStream = minioConfig.getMinioClient().getObject(
                GetObjectArgs.builder()
                        .bucket(minioConfig.getBucketName())
                        .object(filePath)
                        .build())) {

            if (inputStream == null) {
                throw new FileException("无法获取文件输入流");
            }

            return inputStream.readAllBytes();
        } catch (IOException ex) {
            throw new FileException("文件下载失败: " + ex.getMessage(), ex);
        } catch (Exception ex) {
            throw new FileException("发生未知错误: " + ex.getMessage(), ex);
        }
    }

    @Override
    public void deleteFile(String filePath) throws FileException {
        if (filePath == null || filePath.trim().isEmpty()) {
            throw new FileException("文件路径不能为空");
        }

        if (minioConfig == null || minioConfig.getMinioClient() == null) {
            throw new FileException("MinIO配置未初始化");
        }

        try {
            minioConfig.getMinioClient().removeObject(
                    RemoveObjectArgs.builder()
                            .bucket(minioConfig.getBucketName())
                            .object(filePath)
                            .build());
        } catch (ErrorResponseException ex) {
            // 文件不存在或其他MinIO特定错误
            throw new FileException("删除文件失败: " + ex.getMessage(), ex);
        } catch (InsufficientDataException | InternalException |
                 InvalidKeyException | InvalidResponseException |
                 IOException | NoSuchAlgorithmException |
                 ServerException | XmlParserException ex) {
            // MinIO客户端可能抛出的其他异常
            throw new FileException("删除文件时发生错误: " + ex.getMessage(), ex);
        } catch (Exception ex) {
            // 其他未预期的异常
            throw new FileException("发生未知错误: " + ex.getMessage(), ex);
        }
    }
}
